package com.wolfpire.system.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import com.wolfpire.system.common.AuthorityUtils;
import com.wolfpire.system.common.Constants;
import com.wolfpire.system.common.EasyuiPage;
import com.wolfpire.system.common.Page;
import com.wolfpire.system.common.base.dao.IBaseHibernateDao;
import com.wolfpire.system.common.base.service.impl.BaseHibernateService;
import com.wolfpire.system.dao.AuthorityDao;
import com.wolfpire.system.model.Authority;
import com.wolfpire.system.service.AuthorityService;

@Service("authorityService")
public class AuthorityServiceImpl extends BaseHibernateService<Authority, Long>
		implements AuthorityService {

	@Override
	public List<Authority> list(Authority authority) {
		return this.authorityDao.list(authority);
	}

	@Override
	public Page<Authority> setPageDataList(EasyuiPage<Authority> page, Authority filterAuthority) {
		return this.authorityDao.findAuthoritys(page, filterAuthority);
	}

	@Override
	public boolean isUnique(Authority authority) {
		return this.authorityDao.isUniqueName(authority);
	}

	@Override
	public void del(Long id) {
		Authority authority = this.authorityDao.get(id);
		if (null != authority) {
			authority.setDelFlag(Constants.DELETE_FLAG);
			this.authorityDao.saveOrUpdate(authority);
		}
	}
	
	@Override
	public void saveOrUpdate(Authority authority) {
		Long parentId = authority.getParentId();
		if (null != parentId) {
			//判断是否存在父组织，如果存在父组织，将其父组织设置为非叶子节点
			Authority parentAuthority = this.authorityDao.get(parentId);
			parentAuthority.setLeaf(false);
			this.authorityDao.save(parentAuthority);
		}
		if (null != authority.getId()) {
			List<Authority> children = this.findChildRen(authority.getId());
			if (!CollectionUtils.isEmpty(children)) {
				//判断是否存在子节点，如果存在，将其设置为非叶子节点
				authority.setLeaf(false);
			}
		}
		this.authorityDao.saveOrUpdate(authority);
	}

	@Override
	public List<Authority> findChildRen(Long parentId) {
		Authority authority = new Authority();
		authority.setParentId(parentId);
		return this.authorityDao.list(authority);
	}
	
	@Override
	protected IBaseHibernateDao<Authority, Long> getEntityDao() {
		return this.authorityDao;
	}
	
	@Resource private AuthorityDao authorityDao;

	@Override
	public List<Authority> findByUserId(Long userId) {
		return this.authorityDao.findByUserId(userId);
	}

	@Override
	public List<Authority> buildMenuTree(Long userId) {
		// 获取目录和菜单
		List<Authority> authorities = this.authorityDao.getCatalogAndMenuTypeByUserId(userId);
		List<Authority> catalogs = new ArrayList<Authority>();
		List<Authority> menus = new ArrayList<Authority>();
		// 区分
		for (Authority authority : authorities) {
			if (Authority.TYPE_CATALOG.equals(authority.getType())) {
				catalogs.add(authority);
			} else if (Authority.TYPE_MENU.equals(authority.getType())) {
				menus.add(authority);
			}
		}
		// 组合
		for (Authority authority : catalogs) {
			Long id = authority.getId();
			for (Authority a : menus) {
				if (id.longValue() == a.getParentId().longValue()) {
//					authority.getChildrenAuthories().add(a);
					authority.getChildren().add(a);
				}
			}
		}
		return catalogs;
	}

	@Override
	public List<Authority> buildMenuTree(List<Authority> userAuthorities) {
		if (CollectionUtils.isEmpty(userAuthorities)) {
			return new ArrayList<Authority>();
		}
		List<Authority> catalogs = new ArrayList<Authority>();
		List<Authority> menus = new ArrayList<Authority>();
		// 区分
		for (Authority authority : userAuthorities) {
			if (Authority.TYPE_CATALOG.equals(authority.getType())) {
				catalogs.add(authority);
			} else if (Authority.TYPE_MENU.equals(authority.getType())) {
				menus.add(authority);
			}
		}
		// 这里多个角色权限合并后要判断去重
		catalogs = this.removeRepeat(catalogs);
		menus = this.removeRepeat(menus);
		for(Authority authority : catalogs){
			Long id = authority.getId();
			for (Authority a : menus) {
				if (id.longValue() == a.getParentId().longValue()) {
					/*if (!authority.getChildrenAuthories().contains(a)) {
						authority.getChildrenAuthories().add(a);
					}*/
					if (!authority.getChildren().contains(a)) {
						authority.getChildren().add(a);
					}
				}
			}
		}
		// 组合
		/*for (Authority authority : catalogs) {
			Long id = authority.getId();
			for (Authority a : menus) {
				if (id.longValue() == a.getParentId().longValue()) {
					authority.getChildrenAuthories().add(a);
				}
			}
		}*/
		return catalogs;
	}
	
	private List<Authority> removeRepeat(List<Authority> authorities){
		if (CollectionUtils.isNotEmpty(authorities)) {
			List<Authority> resultAuthorites = new ArrayList<Authority>();
			for (Authority authority : authorities) {
				if (!resultAuthorites.contains(authority)) {
					resultAuthorites.add(authority);
				}
			}
			return resultAuthorites;
		}
		return authorities;
	}

	@Override
	public List<Authority> listTree(Authority authority) {
		List<Authority> authoritys = this.authorityDao.listTree(authority);
		List<Authority> roots = new ArrayList<Authority>();
		List<Authority> children = new ArrayList<Authority>();
		Map<Long, Integer> childrenCount = new HashMap<Long, Integer>();
		for (Authority a : authoritys) {
			a.setState("open");
			if (null != a.getParentId()) {
				children.add(a);
				if(null != childrenCount.get(a.getParentId())) {
					childrenCount.put(a.getParentId(), (childrenCount.get(a.getParentId()) + 1));
				} else {
					childrenCount.put(a.getParentId(), 1);
				}
			} else {
				roots.add(a);
			}
		}
		for (Authority root : roots) {
			AuthorityUtils.getChildren(children, root, childrenCount);
		}
		return roots;
	}
	
	/*private void getChildren(List<Authority> authorities, Authority authority, Map<Long, Integer> childrenCount) {
		authority.setState("open");
		Long oId = authority.getId();
		// 当authroity id不为空，且有子节点时候才去获取子节点
		if (null != oId && null != childrenCount.get(oId)) {
//			List<Authority> children = authority.getChildrenAuthories();
			List<Authority> children = authority.getChildren();
			for (Authority a : authorities) {
				if (null != a.getParentId()
						&& oId.equals(a.getParentId())) {
					if (!children.contains(a)) {
						// 获取a 的子节点
						getChildren(authorities, a, childrenCount);
						children.add(a);
					}
				}
			}
		}
		
	}*/
}
